package server.datamodel;

import java.util.ArrayList;
import java.util.Random;

public class Datamodel {

	private static Random random = new Random();
	
	private ArrayList<User> users;
	private ArrayList<CreepSmashGame> games;
	
	private ArrayList<CreepDescription> creepDescriptions = new ArrayList<CreepDescription>();
	private ArrayList<TowerDescription> towerDescriptions = new ArrayList<TowerDescription>();
	
	private Team defaultTeam;

	public Datamodel() {
		games = new ArrayList<CreepSmashGame>();
		users = new ArrayList<User>();
		
		initCreeps();
		
		initTowers();
		
		initTeams();
	}
	
	private void initTeams() {
		defaultTeam = new Team();
		defaultTeam.setName("users");
	}

	private void initTowers() {
		TowerDescription basic1 = new TowerDescription();
		basic1.setName("BASIC");
		basic1.setLevel(1);
		basic1.setPrice(50);
		basic1.setCoolDownMax(650);
		basic1.setColor("00ff00");
		basic1.setRange(1.75);
		basic1.setDamage(25);
		basic1.setDescription("-");
		basic1.setSlowRate(0);
		basic1.setSlowTime(0);
		basic1.setSplashRadius(0);
		basic1.setSplashDamageReduce(0);
		towerDescriptions.add(basic1);
		
		TowerDescription basic2 = new TowerDescription();
		basic2.setName("BASIC");
		basic2.setDescription("-");
		basic2.setLevel(2);
		basic2.setPrice(100);
		basic2.setCoolDownMax(650);
		basic2.setColor("0000ff");
		basic2.setRange(2.0);
		basic2.setDamage(50);
		basic2.setSlowRate(0);
		basic2.setSlowTime(0);
		basic2.setSplashRadius(0);
		basic2.setSplashDamageReduce(0);
		towerDescriptions.add(basic2);

		TowerDescription basic3 = new TowerDescription();
		basic3.setName("BASIC");
		basic3.setDescription("-");
		basic3.setLevel(3);
		basic3.setPrice(1000);
		basic3.setCoolDownMax(650);
		basic3.setColor("ff0000");
		basic3.setRange(2.25);
		basic3.setDamage(250);
		basic3.setSlowRate(0);
		basic3.setSlowTime(0);
		basic3.setSplashRadius(0);
		basic3.setSplashDamageReduce(0);
		towerDescriptions.add(basic3);
		
		TowerDescription basic4 = new TowerDescription();
		basic4.setName("BASIC");
		basic4.setDescription("-");
		basic4.setLevel(4);
		basic4.setPrice(3000);
		basic4.setCoolDownMax(650);
		basic4.setColor("ffc800");
		basic4.setRange(2.5);
		basic4.setDamage(1000);
		basic4.setSlowRate(0);
		basic4.setSlowTime(0);
		basic4.setSplashRadius(0);
		basic4.setSplashDamageReduce(0);
		towerDescriptions.add(basic4);

		TowerDescription slow1 = new TowerDescription();
		slow1.setName("SLOW");
		slow1.setDescription("slows target");
		slow1.setLevel(1);
		slow1.setPrice(100);
		slow1.setCoolDownMax(750);
		slow1.setColor("00ff00");
		slow1.setRange(1.75);
		slow1.setDamage(25);
		slow1.setSlowRate(0.3);
		slow1.setSlowTime(2000);
		slow1.setSplashRadius(0);
		slow1.setSplashDamageReduce(0);
		towerDescriptions.add(slow1);
		
		TowerDescription slow2 = new TowerDescription();
		slow2.setName("SLOW");
		slow2.setDescription("slows target");
		slow2.setLevel(2);
		slow2.setPrice(200);
		slow2.setCoolDownMax(800);
		slow2.setColor("0000ff");
		slow2.setRange(2.25);
		slow2.setDamage(50);
		slow2.setSlowRate(0.35);
		slow2.setSlowTime(2000);
		slow2.setSplashRadius(0);
		slow2.setSplashDamageReduce(0);
		towerDescriptions.add(slow2);

		TowerDescription slow3 = new TowerDescription();
		slow3.setName("SLOW");
		slow3.setDescription("slows target");
		slow3.setLevel(3);
		slow3.setPrice(400);
		slow3.setCoolDownMax(850);
		slow3.setColor("ff0000");
		slow3.setRange(2.5);
		slow3.setDamage(75);
		slow3.setSlowRate(0.45);
		slow3.setSlowTime(2500);
		slow3.setSplashRadius(0);
		slow3.setSplashDamageReduce(0);
		towerDescriptions.add(slow3);

		TowerDescription slow4 = new TowerDescription();
		slow4.setName("SLOW");
		slow4.setDescription("slows multiple targets");
		slow4.setLevel(4);
		slow4.setPrice(3000);
		slow4.setCoolDownMax(900);
		slow4.setColor("ffc800");
		slow4.setRange(2.5);
		slow4.setDamage(100);
		slow4.setSlowRate(0.5);
		slow4.setSlowTime(2500);
		slow4.setSplashRadius(1.25);
		slow4.setSplashDamageReduce(0.7);
		towerDescriptions.add(slow4);

		TowerDescription splash1 = new TowerDescription();
		splash1.setName("SPLASH");
		splash1.setDescription("attacks multiple targets");
		splash1.setLevel(1);
		splash1.setPrice(250);
		splash1.setCoolDownMax(750);
		splash1.setColor("00ff00");
		splash1.setRange(2.0);
		splash1.setDamage(50);
		splash1.setSlowRate(0);
		splash1.setSlowTime(0);
		splash1.setSplashRadius(1.75);
		splash1.setSplashDamageReduce(0.7);
		towerDescriptions.add(splash1);
		
		TowerDescription splash2 = new TowerDescription();
		splash2.setName("SPLASH");
		splash2.setDescription("attacks multiple targets");
		splash2.setLevel(2);
		splash2.setPrice(750);
		splash2.setCoolDownMax(600);
		splash2.setColor("0000ff");
		splash2.setRange(2.25);
		splash2.setDamage(200);
		splash2.setSlowRate(0);
		splash2.setSlowTime(0);
		splash2.setSplashRadius(1.75);
		splash2.setSplashDamageReduce(0.7);
		towerDescriptions.add(splash2);
		
		TowerDescription splash3 = new TowerDescription();
		splash3.setName("SPLASH");
		splash3.setDescription("attacks multiple targets");
		splash3.setLevel(3);
		splash3.setPrice(3000);
		splash3.setCoolDownMax(500);
		splash3.setColor("ff0000");
		splash3.setRange(2.75);
		splash3.setDamage(400);
		splash3.setSlowRate(0);
		splash3.setSlowTime(0);
		splash3.setSplashRadius(1.75);
		splash3.setSplashDamageReduce(0.6);
		towerDescriptions.add(splash3);
		
		TowerDescription splash4 = new TowerDescription();
		splash4.setName("SPLASH");
		splash4.setDescription("attacks multiple targets");
		splash4.setLevel(4);
		splash4.setPrice(7500);
		splash4.setCoolDownMax(500);
		splash4.setColor("ffc800");
		splash4.setRange(3.0);
		splash4.setDamage(1100);
		splash4.setSlowRate(0);
		splash4.setSlowTime(0);
		splash4.setSplashRadius(1.75);
		splash4.setSplashDamageReduce(0.5);
		towerDescriptions.add(splash4);
		
		TowerDescription rocket1 = new TowerDescription();
		rocket1.setName("ROCKET");
		rocket1.setDescription("attacks multiple targets");
		rocket1.setLevel(1);
		rocket1.setPrice(1000);
		rocket1.setCoolDownMax(3750);
		rocket1.setColor("00ff00");
		rocket1.setRange(2.5);
		rocket1.setDamage(1000);
		rocket1.setSlowRate(0);
		rocket1.setSlowTime(0);
		rocket1.setSplashRadius(1.25);
		rocket1.setSplashDamageReduce(0.8);
		towerDescriptions.add(rocket1);
		
		TowerDescription rocket2 = new TowerDescription();
		rocket2.setName("ROCKET");
		rocket2.setDescription("attacks multiple targets");
		rocket2.setLevel(2);
		rocket2.setPrice(3000);
		rocket2.setCoolDownMax(3750);
		rocket2.setColor("0000ff");
		rocket2.setRange(3.0);
		rocket2.setDamage(2500);
		rocket2.setSlowRate(0);
		rocket2.setSlowTime(0);
		rocket2.setSplashRadius(1.25);
		rocket2.setSplashDamageReduce(0.8);
		towerDescriptions.add(rocket2);
		
		TowerDescription rocket3 = new TowerDescription();
		rocket3.setName("ROCKET");
		rocket3.setDescription("attacks multiple targets");
		rocket3.setLevel(3);
		rocket3.setPrice(7500);
		rocket3.setCoolDownMax(3250);
		rocket3.setColor("ff0000");
		rocket3.setRange(3.5);
		rocket3.setDamage(7500);
		rocket3.setSlowRate(0);
		rocket3.setSlowTime(0);
		rocket3.setSplashRadius(1.5);
		rocket3.setSplashDamageReduce(0.7);
		towerDescriptions.add(rocket3);
		
		TowerDescription rocket4 = new TowerDescription();
		rocket4.setName("ROCKET");
		rocket4.setDescription("attacks multiple targets");
		rocket4.setLevel(4);
		rocket4.setPrice(15000);
		rocket4.setCoolDownMax(3000);
		rocket4.setColor("ffc800");
		rocket4.setRange(4.0);
		rocket4.setDamage(15000);
		rocket4.setSlowRate(0);
		rocket4.setSlowTime(0);
		rocket4.setSplashRadius(1.75);
		rocket4.setSplashDamageReduce(0.6);
		towerDescriptions.add(rocket4);
		
		TowerDescription speed1 = new TowerDescription();
		speed1.setName("SPEED");
		speed1.setDescription("-");
		speed1.setLevel(1);
		speed1.setPrice(1000);
		speed1.setCoolDownMax(450);
		speed1.setColor("00ff00");
		speed1.setRange(2.5);
		speed1.setDamage(225);
		speed1.setSlowRate(0);
		speed1.setSlowTime(0);
		speed1.setSplashRadius(0);
		speed1.setSplashDamageReduce(0);
		towerDescriptions.add(speed1);
		
		TowerDescription speed2 = new TowerDescription();
		speed2.setName("SPEED");
		speed2.setDescription("-");
		speed2.setLevel(2);
		speed2.setPrice(3000);
		speed2.setCoolDownMax(350);
		speed2.setColor("0000ff");
		speed2.setRange(2.75);
		speed2.setDamage(450);
		speed2.setSlowRate(0);
		speed2.setSlowTime(0);
		speed2.setSplashRadius(0);
		speed2.setSplashDamageReduce(0);
		towerDescriptions.add(speed2);
		
		TowerDescription speed3 = new TowerDescription();
		speed3.setName("SPEED");
		speed3.setDescription("-");
		speed3.setLevel(3);
		speed3.setPrice(7500);
		speed3.setCoolDownMax(250);
		speed3.setColor("ff0000");
		speed3.setRange(3.0);
		speed3.setDamage(1100);
		speed3.setSlowRate(0);
		speed3.setSlowTime(0);
		speed3.setSplashRadius(0);
		speed3.setSplashDamageReduce(0);
		towerDescriptions.add(speed3);
		
		TowerDescription speed4 = new TowerDescription();
		speed4.setName("SPEED");
		speed4.setDescription("-");
		speed4.setLevel(4);
		speed4.setPrice(15000);
		speed4.setCoolDownMax(150);
		speed4.setColor("ffc800");
		speed4.setRange(3.25);
		speed4.setDamage(1800);
		speed4.setSlowRate(0);
		speed4.setSlowTime(0);
		speed4.setSplashRadius(0);
		speed4.setSplashDamageReduce(0);
		towerDescriptions.add(speed4);
		
		TowerDescription ultimate1 = new TowerDescription();
		ultimate1.setName("ULTIMATE");
		ultimate1.setDescription("-");
		ultimate1.setLevel(1);
		ultimate1.setPrice(20000);
		ultimate1.setCoolDownMax(5000);
		ultimate1.setColor("00ff00");
		ultimate1.setRange(5.0);
		ultimate1.setDamage(25000);
		ultimate1.setSlowRate(0);
		ultimate1.setSlowTime(0);
		ultimate1.setSplashRadius(0);
		ultimate1.setSplashDamageReduce(0);
		towerDescriptions.add(ultimate1);
		
		TowerDescription ultimate2 = new TowerDescription();
		ultimate2.setName("ULTIMATE");
		ultimate2.setDescription("-");
		ultimate2.setLevel(2);
		ultimate2.setPrice(50000);
		ultimate2.setCoolDownMax(2500);
		ultimate2.setColor("ffc800");
		ultimate2.setRange(7.5);
		ultimate2.setDamage(40000);
		ultimate2.setSlowRate(0);
		ultimate2.setSlowTime(0);
		ultimate2.setSplashRadius(0);
		ultimate2.setSplashDamageReduce(0);
		towerDescriptions.add(ultimate2);
	}

	private void initCreeps() {
		CreepDescription mercury = new CreepDescription();
		mercury.setName("MERCURY");
		mercury.setPrice(50);
		mercury.setHealthMax(300);
		mercury.setSpeedMax(1.4);
		mercury.setIncome(5);
		mercury.setBounty(5);
		creepDescriptions.add(mercury);
		
		CreepDescription mako = new CreepDescription();
		mako.setName("MAKO");
		mako.setPrice(100);
		mako.setHealthMax(700);
		mako.setSpeedMax(1.3);
		mako.setIncome(10);
		mako.setBounty(10);
		creepDescriptions.add(mako);
		
		CreepDescription fastNova = new CreepDescription();
		fastNova.setName("FAST NOVA");
		fastNova.setPrice(250);
		fastNova.setHealthMax(1400);
		fastNova.setSpeedMax(1.6);
		fastNova.setIncome(25);
		fastNova.setBounty(25);
		creepDescriptions.add(fastNova);
		
		CreepDescription largeManta = new CreepDescription();
		largeManta.setName("LARGE MANTA");
		largeManta.setPrice(500);
		largeManta.setHealthMax(3500);
		largeManta.setSpeedMax(1.0);
		largeManta.setIncome(50);
		largeManta.setBounty(50);
		creepDescriptions.add(largeManta);
		
		CreepDescription demeter = new CreepDescription();
		demeter.setName("DEMETER");
		demeter.setPrice(1000);
		demeter.setHealthMax(7000);
		demeter.setSpeedMax(1.2);
		demeter.setIncome(90);
		demeter.setBounty(90);
		creepDescriptions.add(demeter);
		
		CreepDescription ray = new CreepDescription();
		ray.setName("RAY");
		ray.setPrice(2000);
		ray.setHealthMax(14000);
		ray.setSpeedMax(1.3);
		ray.setIncome(180);
		ray.setBounty(180);
		creepDescriptions.add(ray);
		
		CreepDescription speedyRaider = new CreepDescription();
		speedyRaider.setName("SPEEDY RAIDER");
		speedyRaider.setPrice(4000);
		speedyRaider.setHealthMax(30000);
		speedyRaider.setSpeedMax(1.8);
		speedyRaider.setIncome(360);
		speedyRaider.setBounty(360);
		creepDescriptions.add(speedyRaider);
		
		CreepDescription bigToucan = new CreepDescription();
		bigToucan.setName("BIG TOUCAN");
		bigToucan.setPrice(8000);
		bigToucan.setHealthMax(80000);
		bigToucan.setSpeedMax(1.2);
		bigToucan.setIncome(720);
		bigToucan.setBounty(720);
		creepDescriptions.add(bigToucan);
		
		CreepDescription vulture = new CreepDescription();
		vulture.setName("VULTURE");
		vulture.setPrice(15000);
		vulture.setHealthMax(140000);
		vulture.setSpeedMax(1.4);
		vulture.setIncome(1200);
		vulture.setBounty(1200);
		creepDescriptions.add(vulture);
		
		CreepDescription shark = new CreepDescription();
		shark.setName("SHARK");
		shark.setPrice(25000);
		shark.setHealthMax(250000);
		shark.setSpeedMax(1.5);
		shark.setIncome(2000);
		shark.setBounty(2000);
		creepDescriptions.add(shark);
		
		CreepDescription racingMamba = new CreepDescription();
		racingMamba.setName("RACING MAMBA");
		racingMamba.setPrice(40000);
		racingMamba.setHealthMax(500000);
		racingMamba.setSpeedMax(2.0);
		racingMamba.setIncome(3200);
		racingMamba.setBounty(3200);
		creepDescriptions.add(racingMamba);
		
		CreepDescription hugeTitan = new CreepDescription();
		hugeTitan.setName("HUGE TITAN");
		hugeTitan.setPrice(60000);
		hugeTitan.setHealthMax(1200000);
		hugeTitan.setSpeedMax(1.3);
		hugeTitan.setIncome(4800);
		hugeTitan.setBounty(4800);
		creepDescriptions.add(hugeTitan);
		
		CreepDescription zeus = new CreepDescription();
		zeus.setName("ZEUS");
		zeus.setPrice(100000);
		zeus.setHealthMax(1500000);
		zeus.setSpeedMax(1.3);
		zeus.setIncome(7000);
		zeus.setBounty(7000);
		creepDescriptions.add(zeus);
		
		CreepDescription phoenix = new CreepDescription();
		phoenix.setName("PHOENIX");
		phoenix.setPrice(200000);
		phoenix.setHealthMax(2500000);
		phoenix.setSpeedMax(1.6);
		phoenix.setIncome(14000);
		phoenix.setBounty(14000);
		creepDescriptions.add(phoenix);
		
		CreepDescription expressRaptor = new CreepDescription();
		expressRaptor.setName("EXPRESS RAPTOR");
		expressRaptor.setPrice(400000);
		expressRaptor.setHealthMax(6000000);
		expressRaptor.setSpeedMax(2.8);
		expressRaptor.setIncome(28000);
		expressRaptor.setBounty(28000);
		creepDescriptions.add(expressRaptor);
		
		CreepDescription fatColossus = new CreepDescription();
		fatColossus.setName("FAT COLOSSUS");
		fatColossus.setPrice(1000000);
		fatColossus.setHealthMax(15000000);
		fatColossus.setSpeedMax(1.4);
		fatColossus.setIncome(56000);
		fatColossus.setBounty(56000);
		creepDescriptions.add(fatColossus);
	}
	
	public void addUser(User user) {
		users.add(user);
	}
	
	public void removeUser(User user) {
		users.remove(user);
	}
	
	public ArrayList<User> getUsers() {
		return users;
	}
	
	public static String generateID(Object object) {
		return object.getClass().getSimpleName() + "@" + Integer.toHexString(random.nextInt());
	}
	
	public void addGame(CreepSmashGame game) {
		games.add(game);
	}
	
	public void removeGame(CreepSmashGame game) {
		games.remove(game);
	}
	
	public ArrayList<CreepSmashGame> getGames() {
		return games;
	}
	
	public ArrayList<TowerDescription> getTowerDescriptions() {
		return towerDescriptions;
	}
	
	public ArrayList<CreepDescription> getCreepDescriptions() {
		return creepDescriptions;
	}

	public Team getDefaultTeam() {
		return defaultTeam;
	}
}
